#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
数据生成脚本
使用Faker生成测试数据并写入SQLite数据库
"""

import os
import sys
from faker import Faker
from faker.providers import lorem, company, internet, date_time
import random
from typing import List, Dict, Any

# 添加项目根目录到Python路径
sys.path.append(os.path.dirname(os.path.abspath(__file__)))

from app.db.database import db
from app.model.model_learn import Learn
from app.model.model_lesson import Lesson

# 初始化Faker，使用中文
fake = Faker('zh_CN')
fake.add_provider(lorem)
fake.add_provider(company)
fake.add_provider(internet)
fake.add_provider(date_time)

class DataGenerator:
    """数据生成器类"""
    def __init__(self):
        self.learns = []
        self.lessons = []
    def generate_learn_data(self, count: int = 50) -> List[Dict[str, Any]]:
        """
        生成学习课程数据
        :param count: 生成数量
        :return: 学习课程数据列表
        """
        print(f"正在生成 {count} 个学习课程...")
        learn_data = []
        for i in range(count):
            # 生成LearnID
            date_str = fake.date(pattern="%Y%m%d")
            version = random.randint(1, 999)
            learnId = f"Learn-{date_str}-v{version}"
            # 生成工序
            processes = [
                "超声波焊接", "激光焊接", "点焊", "氩弧焊", "电阻焊", "摩擦焊",
                "钎焊", "电子束焊", "等离子焊", "气焊", "电弧焊", "埋弧焊"
            ]
            process = random.choice(processes) + str(random.randint(1000, 9999))
            # 生成过程
            procedure = process  # 过程与工序相同
            # 生成子过程
            subProcedure = process[:-1] + str(random.randint(100, 999))
            # 生成标准方案
            standardSolution = "方案" + str(random.randint(1000, 9999))
            # 生成标准名称
            standardName = "标准" + str(random.randint(1000, 9999))
            # 生成体系
            systems = ["NCM", "ISO", "TS", "IATF", "VDA", "QMS"]
            system = random.choice(systems) + " " + str(random.randint(100, 999))
            # 生成平台
            platforms = ["方壳卷绕_M6U", "软包叠片_M6U", "圆柱卷绕_M6U", "方壳叠片_M6U"]
            platform = random.choice(platforms)
            # 生成拉线类型
            lineTypes = ["普遍适用", "专用", "通用", "定制"]
            lineType = random.choice(lineTypes) + str(random.randint(1000, 9999))
            # 生成失效模式
            failureMode = process  # 失效模式与工序相同
            # 生成示意图
            schematicDiagram = "图" + str(random.randint(1000, 9999))
            # 生成固化类别
            fixCategories = ["固化", "临时", "永久", "可逆"]
            fixCateory = random.choice(fixCategories) + str(random.randint(100, 999))
            # 生成标准文件编号
            standardFileNo = "No_A" + str(random.randint(1000, 9999))
            # 生成受控状态
            controlStatuses = ["已受控", "未受控", "其它"]
            controlStatus = random.choice(controlStatuses)
            # 生成落地状态
            landedStatuses = ["已落地", "未落地", "不适用"]
            landedStatus = random.choice(landedStatuses)
            # 生成子系统关联条目
            subSystemRelatedItems = "状态" + str(random.randint(1000, 9999)) + " 查看 链接打开新页面"
            # 生成创建人ID
            creatorId = str(random.randint(10000, 99999))
            # 生成更新人ID（可选）
            updaterId = str(random.randint(10000, 99999)) if random.random() < 0.7 else None
            
            learn_info = {
                'learnId': learnId,
                'process': process,
                'procedure': procedure,
                'subProcedure': subProcedure,
                'standardSolution': standardSolution,
                'standardName': standardName,
                'system': system,
                'platform': platform,
                'lineType': lineType,
                'failureMode': failureMode,
                'schematicDiagram': schematicDiagram,
                'fixCateory': fixCateory,
                'standardFileNo': standardFileNo,
                'controlStatus': controlStatus,
                'landedStatus': landedStatus,
                'subSystemRelatedItems': subSystemRelatedItems,
                'creatorId': creatorId,
                'updaterId': updaterId
            }
            learn_data.append(learn_info)
        
        return learn_data
    
    def generate_lesson_data(self, count: int = 200) -> List[Dict[str, Any]]:
        """
        生成课程数据
        :param count: 生成数量
        :return: 课程数据列表
        """
        print(f"正在生成 {count} 个课程...")
        
        lesson_data = []
        
        for i in range(count):
            # 生成LessonID
            date_str = fake.date(pattern="%Y%m%d")
            version = random.randint(1, 999)
            lessonId = f"Lesson-{date_str}-v{version}"
            # 生成来源
            sources = ["来源1", "来源2", "来源3", "来源4"]
            source = random.choice(sources)
            # 生成失效工序
            processes = ["超声波焊接", "超声波焊接2", "超声波焊接", "超声波焊接4"]
            process = random.choice(processes) + str(random.randint(1000, 9999))
            # 生成工厂
            factories = ["HD1", "HD2", "FD1"]
            factory = random.choice(factories)
            # 生成项目名称
            projectName = "项目" + str(random.randint(1000, 9999))
            # 生成发生时间
            occurenceTime = fake.date_time().strftime("%Y-%m-%d %H:%M")
            # 生成问题类型
            problemTypes = ["设备", "设备2", "设备3", "设备4"]
            problemType = random.choice(problemTypes) + str(random.randint(1000, 9999))
            # 生成FA系统报告
            faReport = "FA-REPORT-" + str(random.randint(1000, 9999))
            # 生成问题描述
            problemDescription = "问题描述-内容-" + str(random.randint(1000, 9999))
            # 生成改善措施
            improvement = "改善措施" + str(random.randint(1000, 9999))
            # 生成创建人
            creator = str(random.randint(10000, 99999))
            # 生成更新人（可选）
            updater = str(random.randint(10000, 99999)) if random.random() < 0.7 else None
            
            lesson_info = {
                'lessonId': lessonId,
                'source': source,
                'process': process,
                'factory': factory,
                'projectName': projectName,
                'occurenceTime': occurenceTime,
                'problemType': problemType,
                'faReport': faReport,
                'problemDescription': problemDescription,
                'improvement': improvement,
                'creator': creator,
                'updater': updater
            }
            lesson_data.append(lesson_info)
        
        return lesson_data
    
    def save_learns_to_db(self, learn_data: List[Dict[str, Any]]) -> List[Learn]:
        """
        将学习课程数据保存到数据库
        :param learn_data: 学习课程数据
        :return: Learn对象列表
        """
        print("正在保存学习课程到数据库...")
        
        learns = []
        for data in learn_data:
            learn = Learn(
                learnId=data['learnId'],
                process=data['process'],
                procedure=data['procedure'],
                subProcedure=data['subProcedure'],
                standardSolution=data['standardSolution'],
                standardName=data['standardName'],
                system=data['system'],
                platform=data['platform'],
                lineType=data['lineType'],
                failureMode=data['failureMode'],
                schematicDiagram=data['schematicDiagram'],
                fixCateory=data['fixCateory'],
                standardFileNo=data['standardFileNo'],
                controlStatus=data['controlStatus'],
                landedStatus=data['landedStatus'],
                subSystemRelatedItems=data['subSystemRelatedItems'],
                creatorId=data['creatorId'],
                updaterId=data['updaterId']
            )
            learn.save()
            learns.append(learn)
        
        print(f"成功保存 {len(learns)} 个学习课程")
        return learns
    
    def save_lessons_to_db(self, lesson_data: List[Dict[str, Any]]) -> List[Lesson]:
        """
        将课程数据保存到数据库
        :param lesson_data: 课程数据
        :return: Lesson对象列表
        """
        print("正在保存课程到数据库...")
        
        lessons = []
        for data in lesson_data:
            lesson = Lesson(
                lessonId=data['lessonId'],
                source=data['source'],
                process=data['process'],
                factory=data['factory'],
                projectName=data['projectName'],
                occurenceTime=data['occurenceTime'],
                problemType=data['problemType'],
                faReport=data['faReport'],
                problemDescription=data['problemDescription'],
                improvement=data['improvement'],
                creator=data['creator'],
                updater=data['updater']
            )
            lesson.save()
            lessons.append(lesson)
        
        print(f"成功保存 {len(lessons)} 个课程")
        return lessons
    
    def create_learn_lesson_associations(self, learns: List[Learn], lessons: List[Lesson]):
        """
        创建学习课程与课程的关联关系
        :param learns: 学习课程列表
        :param lessons: 课程列表
        """
        print("正在创建学习课程与课程的关联关系...")
        
        association_count = 0
        
        for learn in learns:
            # 每个学习课程关联3-8个课程
            num_lessons = random.randint(3, min(8, len(lessons)))
            selected_lessons = random.sample(lessons, num_lessons)
            
            for lesson in selected_lessons:
                try:
                    learn.add_lesson(lesson.id)
                    association_count += 1
                except:
                    # 忽略重复关联的错误
                    pass
        
        print(f"成功创建 {association_count} 个关联关系")
    
    def clear_existing_data(self):
        """清空现有数据"""
        print("正在清空现有数据...")
        
        # 清空关联表
        db.clear_table("learn_lesson")
        print("已清空 learn_lesson 表")
        
        # 清空主表
        db.clear_table("lesson")
        print("已清空 lesson 表")
        
        db.clear_table("learn")
        print("已清空 learn 表")
    
    def generate_all_data(self, learn_count: int = 50, lesson_count: int = 200):
        """
        生成所有数据
        :param learn_count: 学习课程数量
        :param lesson_count: 课程数量
        """
        print("=" * 50)
        print("开始生成测试数据")
        print("=" * 50)
        
        # 清空现有数据
        self.clear_existing_data()
        
        # 生成学习课程数据
        learn_data = self.generate_learn_data(learn_count)
        learns = self.save_learns_to_db(learn_data)
        
        # 生成课程数据
        lesson_data = self.generate_lesson_data(lesson_count)
        lessons = self.save_lessons_to_db(lesson_data)
        
        # 创建关联关系
        self.create_learn_lesson_associations(learns, lessons)
        
        print("=" * 50)
        print("数据生成完成！")
        print(f"生成了 {len(learns)} 个学习课程")
        print(f"生成了 {len(lessons)} 个课程")
        print(f"数据库文件: {db.db_path}")
        print("=" * 50)

def main():
    """主函数"""
    print("PIC_UI_API 数据生成器")
    print("使用Faker生成测试数据")
    
    # 获取用户输入
    try:
        learn_count = int(input("请输入要生成的学习课程数量 (默认50): ") or "50")
        lesson_count = int(input("请输入要生成的课程数量 (默认200): ") or "200")
    except ValueError:
        print("输入无效，使用默认值")
        learn_count = 50
        lesson_count = 200
    
    # 确认生成
    print(f"\n将生成:")
    print(f"- {learn_count} 个学习课程")
    print(f"- {lesson_count} 个课程")
    print(f"- 自动创建关联关系")
    
    confirm = input("\n确认生成数据? (y/N): ").lower()
    if confirm not in ['y', 'yes', '是']:
        print("已取消数据生成")
        return
    
    # 生成数据
    generator = DataGenerator()
    generator.generate_all_data(learn_count, lesson_count)

if __name__ == "__main__":
    main()